package com.bacon.gmall.cart.service.impl;

import com.bacon.gmall.cart.mapper.CartMapper;
import com.bacon.gmall.cart.service.CartService;
import com.bacon.gmall.common.constant.RedisConst;
import com.bacon.gmall.common.util.AuthContextHolder;
import com.bacon.gmall.model.cart.CartInfo;
import com.bacon.gmall.model.product.SkuInfo;
import com.bacon.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author： bacon、
 * @version： 1.0
 * @create： 2021-01-04 16:22
 * @description:
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public CartInfo addToCart(Long skuId, Integer skuNum, String userId) {
        /**
         * 1、查询购物车列表
         * 优先前  使用DB
         */
        if (null == skuId || null == skuNum) {
            return null;
        }

        // CartInfo cartInfo = cartMapper.selectOne(
        // new QueryWrapper<CartInfo>().eq("user_id", userId).eq("sku_id", skuId));
        /**
         * 优先后 使用Redis
         */
        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().
                get(RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX,
                        skuId.toString());
        //2、判断是否为同款
        if (null == cartInfo) {
            //4、不是同款,追加的新商品
            cartInfo = new CartInfo();
            cartInfo.setSkuNum(skuNum); //购买数量
            cartInfo.setSkuId(skuId); //购买Id
            cartInfo.setUserId(userId); //购买人的id
            cartInfo.setIsChecked(CartInfo.isCheckedTrue); //是否选中

            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cartInfo.setSkuPrice(skuInfo.getPrice()); //价格
            cartInfo.setCartPrice(skuInfo.getPrice()); //实时价格
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg()); //默认图片
            cartInfo.setSkuName(skuInfo.getSkuName());  //名字
            cartMapper.insert(cartInfo);
        } else {
            //3、是同款,追加数量
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setIsChecked(CartInfo.isCheckedTrue);
            cartMapper.updateById(cartInfo);
        }
        return cartInfo;
    }

    @Override
    public CartInfo findCartInfoBySkuId(Long skuId, String userId) {

        CartInfo cartInfo = (CartInfo) redisTemplate.opsForHash().
                get(RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX,
                        skuId.toString());
        if (null == cartInfo) {
            cartInfo = cartMapper.selectOne(new QueryWrapper<CartInfo>().
                    eq("sku_id", skuId).
                    eq("user_id", userId));
        }
        return cartInfo;

    }

    @Override
    public List<CartInfo> cartList(String userId, String userTempId) throws InterruptedException {

        //获取集合
        List<CartInfo> userIdCartList = getCartInfoList(userId);
        List<CartInfo> userTempIdCartList = getCartInfoList(userTempId);

        //根据集合的有无，所做的判断
        if (!CollectionUtils.isEmpty(userIdCartList)) {
            if (!CollectionUtils.isEmpty(userTempIdCartList)) {
                //3、userId和userTempId都不为空
                //转化为Map集合
                Map<Long, CartInfo> cartInfoMap = userIdCartList.stream().collect(
                        Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));

                //循环遍历临时购物车，将其转化为真正的用户购物车
                userTempIdCartList.forEach(userTempIdCartInfo -> {
                    CartInfo cartInfo = cartInfoMap.get(userTempIdCartInfo.getSkuId());

                    if (null != cartInfo) {
                        //临时购物车和用户购物车有相同商品，进行合并
                        cartInfo.setSkuNum(cartInfo.getSkuNum() + userTempIdCartInfo.getSkuNum());
                        cartMapper.updateById(cartInfo);

                        //删除redis缓存，不然会造成再次挑选商品添加会重复添加缓存中的内容
                        cartMapper.deleteById(userTempIdCartInfo);
                    } else {
                        //临时购物车和用户购物车没有相同商品，将临时用户转化为真正用户
                        cartInfoMap.put(userTempIdCartInfo.getSkuId(), userTempIdCartInfo);
                        userTempIdCartInfo.setUserId(userId);
                        cartMapper.updateById(userTempIdCartInfo);
                    }
                });

                redisTemplate.delete(RedisConst.USER_KEY_PREFIX + userTempId + RedisConst.USER_CART_KEY_SUFFIX);
                return new ArrayList<>(cartInfoMap.values());
            }

            //2、userTempId为空
            return userIdCartList;
        } else {
            //1、userId为空c

            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);

            //批量操作所以userId 为临时用户购物车，改为真正用户购物车
            cartMapper.update(cartInfo, new QueryWrapper<CartInfo>().eq("user_id", userTempId));

            //清理临时用户缓存
            redisTemplate.delete(RedisConst.USER_KEY_PREFIX + userTempId + RedisConst.USER_CART_KEY_SUFFIX);
            return userTempIdCartList;
        }
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(userId)) {
            userId = AuthContextHolder.getUserTempId(request);
        }
        CartInfo cartInfo = new CartInfo();
        cartInfo.setIsChecked(isChecked);
        cartMapper.update(cartInfo, new QueryWrapper<CartInfo>().
                eq("sku_id", skuId).eq("user_id", userId));
    }

    @Override
    public List<CartInfo> findCartListByIsChecked(String userId) {


        /*List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX);*/
        List<CartInfo> cartInfoList = getCartInfoList(userId);

        //使用Stream流 中的filter进行对是否被选中进行筛选
        List<CartInfo> infoList = cartInfoList.stream().filter(cartInfo -> {
            return cartInfo.getIsChecked().equals(1);
        }).collect(Collectors.toList());

        return infoList;
    }

    //查询当前用户购物车集合
    public List<CartInfo> getCartInfoList(String userId) {

        //先使用查询redis ， 后使用DB
        List<CartInfo> userIdCartList = redisTemplate.opsForHash().values(RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX);
        if (CollectionUtils.isEmpty(userIdCartList)) {
            userIdCartList = cartMapper.selectList(new QueryWrapper<CartInfo>().eq("user_id", userId));
        }

        //实时价格
        userIdCartList.forEach(cartInfo -> {
            cartInfo.setSkuPrice(productFeignClient.getPrice(cartInfo.getSkuId()));
        });

        //根据id从小到大排序
        userIdCartList.stream().sorted(new Comparator<CartInfo>() {
            @Override
            public int compare(CartInfo o1, CartInfo o2) {
                return (int) (o1.getId() - o2.getId());
            }
        }).collect(Collectors.toList());

        return userIdCartList;
    }
}
